package com.bjc.wxpay.controller;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.bjc.base.bean.request.BookCartReqVO;
import com.bjc.base.bean.request.BookStockReqVO;
import com.bjc.base.bean.request.BorrowReturnLogReqVO;
import com.bjc.base.bean.request.OrderDetailReqVO;
import com.bjc.base.bean.request.OrderReqVO;
import com.bjc.base.bean.request.PayLogReqVO;
import com.bjc.base.bean.request.UserReqVO;
import com.bjc.base.bean.response.BookCartVO;
import com.bjc.base.bean.response.BookStockVO;
import com.bjc.base.bean.response.BookVO;
import com.bjc.base.bean.response.BorrowReturnLogVO;
import com.bjc.base.bean.response.OrderDetailVO;
import com.bjc.base.bean.response.OrderVO;
import com.bjc.base.service.IBookCartService;
import com.bjc.base.service.IBookStockService;
import com.bjc.base.service.IBorrowReturnLogService;
import com.bjc.base.service.IOrderDetailService;
import com.bjc.base.service.IOrderService;
import com.bjc.base.service.IPayLogService;
import com.bjc.base.service.IUserService;
import com.bjc.base.utils.StringUtil;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;

@Service
public class PayServiceImpl implements IPayService {

	@Autowired
	private IUserService userService;
	@Autowired
	private IBookCartService bookCartService;
	@Autowired
	private IBookStockService bookStockService;
	@Autowired
	private IOrderService orderService;
	@Autowired
	private IOrderDetailService orderDetailService;
	@Autowired
	private IBorrowReturnLogService borrowReturnLogService;
	@Autowired
	private IPayLogService payLogService;

	// @Transactional(rollbackFor = Exception.class)
	@Override
	public Integer createOrder(Integer userId, String cartIds, String outTradeNo) {
		// 发起支付，取出购物车，1.添加订单。2.添加订单详情。3.删除购物车
		// 将订单添加单数据库
		BookCartReqVO bookCartReqVO = new BookCartReqVO();
		bookCartReqVO.setIds(cartIds);
		List<BookCartVO> bookCartVOs = bookCartService.getList(bookCartReqVO);
		if (bookCartVOs == null || bookCartVOs.size() == 0) {
			return 0;
		}
		List<OrderDetailReqVO> detailReqVOs = new ArrayList<>();
		BigDecimal totalPrice = new BigDecimal(0);

		String orderType = "borrow";
		for (BookCartVO bookCartVO : bookCartVOs) {
			BookVO book = bookCartVO.getBook();
			Integer bookId = bookCartVO.getBid(); // 库存id
			Integer pid = bookCartVO.getPid(); // 借阅点id
			Integer borrowWeeks = bookCartVO.getBorrowWeeks();
			orderType = bookCartVO.getCartType();

			BigDecimal needRmbAmount = book.getBorrowPrice();
			totalPrice = totalPrice.add(needRmbAmount.multiply(new BigDecimal(borrowWeeks)));

			OrderDetailReqVO detailReqVO = new OrderDetailReqVO();
			detailReqVO.setBid(bookId);
			detailReqVO.setBorrowWeeks(borrowWeeks);
			LocalDateTime now = LocalDateTime.now();
			detailReqVO.setBorrowStartTime(now);
			// LocalDateTime endTime = now.plusWeeks(borrowWeeks);
			// detailReqVO.setBorrowEndTime(endTime);
			detailReqVO.setPid(pid);
			detailReqVO.setRmbAmount(needRmbAmount);
			// detailReqVO.setXybAmount(xybAmount); // 小鱼币应该从总订单里面扣，不应该从详情???????
			detailReqVOs.add(detailReqVO);
		}

		OrderReqVO orderReqVO = new OrderReqVO();
		orderReqVO.setUid(userId);
		orderReqVO.setOutTradeNo(outTradeNo);
		orderReqVO.setOrderType(orderType);
		// 优惠价格，每满1元减0.05
		// double youhui = (totalPrice.intValue() * 0.05);
		// totalPrice = totalPrice.subtract(new BigDecimal(youhui));
		orderReqVO.setRmbAmount(totalPrice);
		// orderReqVO.setXybAmount(totalPrice);
		// 状态设为待支付
		orderReqVO.setStatus(2);

		// 将订单添加至数据库
		orderService.insert(orderReqVO);
		Integer orderId = orderReqVO.getId();

		// 将订单详情添加至数据库
		for (OrderDetailReqVO orderDetailReqVO : detailReqVOs) {
			orderDetailReqVO.setOrderId(orderId);
			orderDetailService.insert(orderDetailReqVO);
		}
		// 删除购物车
		bookCartService.deleteList(cartIds);
		return orderId;
	}

	// @Transactional(rollbackFor = Exception.class)
	@Override
	public void payNotify(String outTradeNo) {
		// 支付成功后，1.修改订单状态。2.添加借阅信息。3.修改库存状态。4.添加支付记录。5.修改分享人积分
		OrderReqVO orderReqRecord = new OrderReqVO();
		orderReqRecord.setOutTradeNo(outTradeNo);
		OrderVO orderRecord = orderService.get(orderReqRecord);

		// 如果订单已经支付，则不再进行支付回调
		if (orderRecord.getStatus() > 2) {
			return;
		}

		String orderType = orderRecord.getOrderType();
		Integer uid = orderRecord.getUid();
		// 1. 将订单详情里的绘本修改库存状态
		OrderDetailReqVO detailReqVO = new OrderDetailReqVO();
		detailReqVO.setOrderId(orderRecord.getId());
		List<OrderDetailVO> detailVOs = orderDetailService.getList(detailReqVO);
		detailVOs.stream().forEach(s -> {
			if ("borrow".equals(orderType)) {
				borrowHandler(s, uid);
			} else if ("renew".equals(orderType)) {
				renewHandler(s);
			}

		});

		orderReqRecord.setStatus(3); // 已支付
		orderService.update(orderReqRecord);

		// 4.添加支付记录
		PayLogReqVO payLogReqVO = new PayLogReqVO();
		payLogReqVO.setFormUid(orderRecord.getUid());
		payLogReqVO.setLogType(orderType);
		BigDecimal mbAmount = orderRecord.getRmbAmount();
		payLogReqVO.setPayType(1);
		payLogReqVO.setRmbAmount(mbAmount);
		payLogReqVO.setXybAmount(orderRecord.getXybAmount());
		payLogService.insert(payLogReqVO);

		// 5.如果该库存的分享人不为空，支付成功后，则增加分享人积分和小鱼币
		detailVOs.stream().forEach(s -> {
			BookStockVO bookStockVO = bookStockService.getById(s.getBid());
			String ownerUid = bookStockVO.getOwnerUid();
			if (!StringUtil.isNullOrEmpty(ownerUid)) {
				// 1元=1积分=100小鱼币
				UserReqVO userReqVO = new UserReqVO();
				userReqVO.setId(Integer.parseInt(ownerUid));
				int total = mbAmount.multiply(new BigDecimal(100)).intValue();
				userReqVO.setChBalancePlus(mbAmount.doubleValue());
				userReqVO.setXybBalancePlus(total);
				userService.update(userReqVO);
			}

		});

	}

	/**
	 * 处理借阅订单 1.会将库存修改为已借阅 2.添加借阅信息
	 * 
	 * @param orderRecord
	 */
	private void borrowHandler(OrderDetailVO s, Integer uid) {
		Integer bid = s.getBid();

		BookStockReqVO bookStockReqVO = new BookStockReqVO();
		bookStockReqVO.setId(bid);
		bookStockReqVO.setIsLock(1); // 已被借阅
		bookStockReqVO.setBorrowCountAdd(1); // 增加借阅次数
		bookStockService.update(bookStockReqVO);

		// 首先查询该绘本是否已被借阅，如果已被借阅且未归还，则现在自动归还
		BorrowReturnLogReqVO borrowReturnLogReqVO = new BorrowReturnLogReqVO();
		borrowReturnLogReqVO.setBid(bid);
		borrowReturnLogReqVO.setState(1);
		List<BorrowReturnLogVO> borrowReturnLogVOs = borrowReturnLogService.getList(borrowReturnLogReqVO);
		if (borrowReturnLogVOs != null && borrowReturnLogVOs.size()>0) {
			for (BorrowReturnLogVO borrowReturnLogVO : borrowReturnLogVOs) {
				BorrowReturnLogReqVO borrowReturnLogReqVOUpdate = new BorrowReturnLogReqVO();
				borrowReturnLogReqVOUpdate.setId(borrowReturnLogVO.getId());
				borrowReturnLogReqVOUpdate.setState(2);
				borrowReturnLogReqVOUpdate.setReturnPid(s.getPid());
				borrowReturnLogReqVOUpdate.setBorrowStartTime(LocalDateTime.now());
				borrowReturnLogReqVOUpdate.setRemark("系统自动归还");
				borrowReturnLogService.update(borrowReturnLogReqVOUpdate);
			}
			
		}

		// 添加借阅信息
		borrowReturnLogReqVO.setUid(uid);
		borrowReturnLogReqVO.setState(1);
		// 设置借阅点
		borrowReturnLogReqVO.setPid(s.getPid());
		borrowReturnLogReqVO.setBorrowStartTime(s.getBorrowStartTime());
		borrowReturnLogReqVO.setBorrowWeeks(s.getBorrowWeeks());
		borrowReturnLogService.insert(borrowReturnLogReqVO);
	}

	/**
	 * 处理续借订单 1.累加借阅天数
	 * 
	 * @param orderRecord
	 */
	private void renewHandler(OrderDetailVO s) {
		Integer bid = s.getBid();
		BookStockReqVO bookStockReqVO = new BookStockReqVO();
		bookStockReqVO.setId(bid);
		bookStockReqVO.setIsLock(1); // 已被借阅
		bookStockReqVO.setBorrowCountAdd(1); // 增加借阅次数
		bookStockService.update(bookStockReqVO);

		BorrowReturnLogReqVO borrowReturnLogReqVO = new BorrowReturnLogReqVO();
		borrowReturnLogReqVO.setBid(bid);
		BorrowReturnLogVO borrowReturnLogVO = borrowReturnLogService.get(borrowReturnLogReqVO);
		Integer resultBorrowWeeks = borrowReturnLogVO.getBorrowWeeks() + s.getBorrowWeeks();
		borrowReturnLogReqVO.setBorrowWeeks(resultBorrowWeeks);
		borrowReturnLogService.update(borrowReturnLogReqVO);
	}

	private void adddBorrowCount(OrderDetailVO s) {

	}

}
